﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;
using Kooboo.CMS.SiteConverter.Parser;

namespace Kooboo.CMS.SiteConverter.Winform
{
    public partial class Form1 : Form
    {
        public const string DefaultOutputName = "OutputSite.zip";

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            this.chkExceptions.Checked = Kooboo.HtmlFunc.AnalysisSetting.ThrowAnalysisExceptions;
            this.chkRemoveMarkers.Checked = Kooboo.CMS.SiteConverter.ParserSetting.RemoveFuncMarkers;
        }

        private void Form1_DoubleClick(object sender, EventArgs e)
        {
            var baseDirectory = AppDomain.CurrentDomain.BaseDirectory;
            if (!baseDirectory.EndsWith(@"bin\Debug\")) { return; }

            // default the test html template
            var testDirectory = Path.Combine(baseDirectory.Substring(0, baseDirectory.Length - @"bin\Debug\".Length), "test");
            this.txtInput.Text = testDirectory;

            // default the output directory
            var outputDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
            this.txtOutput.Text = Path.Combine(outputDirectory, DefaultOutputName);
        }

        private void btnSelectDirectory_Click(object sender, EventArgs e)
        {
            var browser = new FolderBrowserDialog();
            var result = browser.ShowDialog();
            if (result == DialogResult.OK)
                this.txtInput.Text = browser.SelectedPath + Path.DirectorySeparatorChar;
        }

        private void btnSelectZipfile_Click(object sender, EventArgs e)
        {
            var browser = new OpenFileDialog();
            browser.Filter = "Zip File(*.zip)|*.zip|All File(*.*)|*.*";
            var result = browser.ShowDialog();
            if (result == DialogResult.OK)
                this.txtInput.Text = browser.FileName;
        }

        private void btnSelectOutput_Click(object sender, EventArgs e)
        {
            var browser = new FolderBrowserDialog();
            var result = browser.ShowDialog();
            if (result == DialogResult.OK)
                this.txtOutput.Text = Path.Combine(browser.SelectedPath, DefaultOutputName);
        }

        private void btnParse_Click(object sender, EventArgs e)
        {
            var isSelectedZip = !string.IsNullOrEmpty(Path.GetExtension(this.txtInput.Text));
            if (isSelectedZip)
            {
                if (!File.Exists(this.txtInput.Text))
                {
                    MessageBox.Show("Can not find the input file.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    this.txtInput.SelectAll();
                    return;
                }
            }
            else
            {
                if (!Directory.Exists(this.txtInput.Text))
                {
                    MessageBox.Show("Can not find the input directory.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    this.txtInput.SelectAll();
                    return;
                }
            }

            var outputDirectory = Path.GetDirectoryName(this.txtOutput.Text);
            if (!Directory.Exists(outputDirectory))
            {
                MessageBox.Show("Can not find the output directory.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
                this.txtOutput.SelectAll();
                return;
            }
            if (Path.GetExtension(this.txtOutput.Text).ToLower() != ".zip")
            {
                MessageBox.Show("Output file must be a zip file type.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
                this.txtOutput.Focus();
                this.txtOutput.Select(outputDirectory.Length + 1, this.txtOutput.Text.Length - outputDirectory.Length);
                return;
            }

            var success = false;
            this.Enabled = false;

            try
            {
                var parserType = ParserType.Razor;
                switch (this.cmbParserType.Text)
                {
                    case "Razor":
                        parserType = ParserType.Razor; break;

                    case "WebForm":
                        parserType = ParserType.WebForm; break;

                    case "NVelocity":
                        parserType = ParserType.NVelocity; break;

                    default: break;
                }
                var encoding = GetEncoding(cmbEncoding.Text);
                var inputStream = new MemoryStream();
                if (isSelectedZip)
                {
                    var bytes = File.ReadAllBytes(this.txtInput.Text);
                    inputStream.Write(bytes, 0, bytes.Length);
                }
                else
                {
                    var inputZip = new Ionic.Zip.ZipFile(encoding);
                    inputZip.AddFiles(Directory.GetFiles(this.txtInput.Text, "*", SearchOption.AllDirectories));
                    inputZip.Save(inputStream);
                }

                inputStream.Position = 0;
                var outputStream = new MemoryStream();
                ParserUtility.ParseZip(inputStream, outputStream, encoding, parserType);
                File.WriteAllBytes(this.txtOutput.Text, outputStream.ToArray());

                success = true;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            this.Enabled = true;
            if (success)
            {
                try { Directory.Delete(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Cms_Data"), true); }
                catch (Exception) { }
                MessageBox.Show("Parse complete!", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }
        private Encoding GetEncoding(string encodingName)
        {
            switch (encodingName)
            {
                case "ANSI":
                    return Encoding.ASCII;
                case "Unicode":
                    return Encoding.Unicode;
                case "Unicode big endian":
                    return Encoding.BigEndianUnicode;
                case "UTF-8":
                    return Encoding.UTF8;
                default:
                    return Encoding.GetEncoding(encodingName);
                    break;
            }
        }
        private void chkExceptions_CheckedChanged(object sender, EventArgs e)
        {
            Kooboo.HtmlFunc.AnalysisSetting.ThrowAnalysisExceptions = this.chkExceptions.Checked;
        }

        private void chkRemoveMarkers_CheckedChanged(object sender, EventArgs e)
        {
            Kooboo.CMS.SiteConverter.ParserSetting.RemoveFuncMarkers = this.chkRemoveMarkers.Checked;
        }
    }
}
